#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <sys/mman.h>

//$ objdump -s identifyCompiler | less
#define IDENTIFY_FALSE 0
#define IDENTIFY_TRUE  !IDENTIFY_FALSE

int is_compressed(off_t size, char * data)
{
	off_t offset;
	uint32_t bytes[256];
	uint16_t pos;
	uint16_t count = 0;
	uint32_t average = 0;

	// initialize
	for(pos=0;pos<256;pos++)
	{
		bytes[pos] = 0;
	}

	// count
	for(offset=0;offset<size;offset++)
	{
		bytes[data[offset]]++;
	}

	// sort
	//@todo

	// show
	//printf("Points\n");
	for(pos=0;pos<256;pos++)
	{
		if ( 0 != bytes[pos] )
		{
			printf("%d = %d\n", pos, bytes[pos]);
			average+=bytes[pos];
			count++;
		}
	}
	average=average/count;
	printf("average: %d (%.3lu%%)\n", average, (average * 100)/size);
	return IDENTIFY_FALSE;
}

// rudimentary GCC detection
int is_gcc(off_t size, char * data)
{
	off_t offset;
	char identify[] = "gcc";
	char *identify_ptr = identify;

	for(offset=0;offset<size;offset++)
	{
		if ( *identify_ptr == data[offset] )
		{
			identify_ptr++;
			unsigned int s_identify = identify_ptr-identify;
			if ( s_identify > strlen(identify) )
			{
				return IDENTIFY_TRUE;
			}
		}
	}
	return IDENTIFY_FALSE;
}

int main(int argc, char * argv[])
{
	int descriptor;
	off_t size;
	void * data;

	descriptor = open(argv[1], O_RDONLY);
	if ( -1 == descriptor )
	{
		return EXIT_FAILURE;
	}
	size = lseek(descriptor, 0, SEEK_END);
	data = mmap(0, size, PROT_READ, MAP_SHARED, descriptor, 0);
	if ( MAP_FAILED != data )
	{
		/*
		if ( IDENTIFY_TRUE == is_gcc(size, data) )
		{
			printf("Found\n");
		}
		*/
		is_compressed(size, data);
	}
	close(descriptor);
	return EXIT_SUCCESS;
}
